iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 4
0
自我挑戰組

跟 VueJS 認識的30天系列 第 4

[DAY04]跟 Vue.js 認識的30天 - Vue 的資料偵聽(watch)

  • 分享至 

  • xImage
  •  

之前也都沒使用過 watch ,所以趁這個機會好好了解一下它。

如何使用偵聽屬性(watch)

基礎範例

const vm = new Vue({
  el:'#app',
  data:{
    msg:''
  },
  watch:{
    //被偵聽的資料名稱(新值,舊值){}
    msg(newMsg,oldMsg){
      console.log('newMsg',newMsg)
      console.log('oldMsg',oldMsg)
    }
  }
})

watch 裡的 msg代表的就是我們所偵聽的資料( datamsg),當偵聽的資料值發生變化時,就會去執行 watch 裡的 msg() ,而 msg(newMsg,oldMsg) 裡的參數一定是先新後舊。

加入 handler 方法及屬性 immediatedeep

handler 方法及 immediate屬性

const vm = new Vue({
  el:'#app',
  data:{
    msg:'',
    msg2:'',
    user:{
      firstName: 'John',
      lastName:'Smith',
      age:0
    },
    user2:{
      firstName: 'Mary',
      lastName:'Wonder',
      age:0
    }
  },
  watch:{
    msg(newMsg,oldMsg){
      console.log('newMsg',newMsg)
      console.log('oldMsg',oldMsg)
      this.user.age = 30
    },
    msg2: {
      handler(newMsg2,oldMsg2){
        this.user2.age = 20
      },
      immediate:true
    }
  }
})

https://ithelp.ithome.com.tw/upload/images/20200918/201275534ZG2zVkemM.png

比較 watchmsgmsg2 的差別,會發現 user.age 的值會是原始值0,但是 user2.age 的值卻是執行 watchmsg2 後的結果,雖然 Vue 在實例化的過程中會先遍歷過所有 watch 裡所有物件的屬性,但卻不會去執行這些物件,而是等到他們所監聽的資料有所改變的時候,才會去執行裡面的方法,除非是加入了 immediate 這個屬性。
immediate 屬性的作用就是在最初綁定這個物件( msg2 )的時候( created() 前),就去執行這個物件的方法( handler() ),所以在畫面一開始 user2.age 就會呈現經過 watchmsg2 作用後的結果值20。

偵聽物件屬性

  • 使用 deep屬性

    const vm = new Vue({
      el:'#app',
      data:{
        cellPhone:{
          type:'apple',
          years:2
        }
      },
      watch:{
        cellPhone: {
          handler(newcellPhone,oldcellPhone){
            console.log(this.cellPhone)
          },
          immediate:true,
          // deep:true
        }
      },
      created(){
        this.cellPhone = {
          msg:'重新賦值可以被偵聽到',
          type:'Samsung',
          years:10
        }
      }
    })
    

    當修改 cellPhone.type 值時, watch 裡的 cellPhone{handler...} 並不會執行,這是因為 Vue 沒辦法偵聽到物件裡的屬性變化,而只能偵聽到物件的變化,像是重新賦值之類的。
    如果要偵聽到物件裡的屬性變化,就必須加入 deep 屬性,這樣當 cellPhone 物件裡不管哪個屬性改變時,都會觸發 watch 裡的 cellPhone{handler...}

  • 使用字串作為偵聽對象

    const vm = new Vue({
      el:'#app',
      data:{
        cellPhone:{
          type:'apple',
          years:2
        },
        cellPhone2:{
          type:'oppo',
          years:1
        }
      },
      watch:{
        'cellPhone2.type': {
          handler(newcellPhone,oldcellPhone){
            console.log(this.cellPhone2)
          },
          immediate:true
        }
      }
    })
    

    偵聽的對象就是物件裡的屬性,只有指定的這個屬性有改變時才會觸發 watch 裡偵聽的對象裡的方法。

比較上述2種寫法的差別:

  • 作法一(使用 deep 屬性):能夠偵聽到 cellPhone 裡所有的屬性,只要其中一個(如 typeyears)有改變,那麼就會執行 watch 裡的 cellPhone{handler...}
  • 作法二(使用字串表示偵聽的資料):只能夠偵聽到 cellPhone2.type ,只有 cellPhone2.type 有改變,才會去執行 watch 裡的 cellPhone2{handler...}

immediate 或是 deep 屬性默認值都是 false ,如果要加入 immediate 或是 deep 屬性,那麼寫法就需變成物件形式,如 msg2: {handler(){...},immediate:true,deep:true}handler 就是在資料改變時要執行的方法,而 immediate 屬性指的是在最初綁定時就要去執行 handler 方法, deep 屬性指的是能夠讀取資料裡更深層的資料(像是 cellPhone 裡的 typeyears )。

watchcomputed 使用時機

  • `watchˋ 對於偵聽的資料有改變,可以去執行一些事情,像是異步處理。
  • computedgetter 方法只能接收它所依賴的響應式資料的改變,之後返回一個值,而 setter 方法是在本身值改變時,才能執行一些事情,但是本身的值還是 getter 方法所得到值。

Demo:[DAY04]跟 Vue.js 認識的30天 - Vue 的資料偵聽(watch)

參考資料:
Vue.js-watch

杭州程序员张张-Vue.js中 watch 的高级用法

龙恩0707-vue系列---理解Vue中的computed,watch,methods的区别及源码实现(六)

Yes


上一篇
[DAY03]跟 Vue.js 認識的30天 - Vue 的資料計算(computed)
下一篇
[DAY05]跟 Vue.js 認識的30天 - Vue 的屬性綁定
系列文
跟 VueJS 認識的30天21
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

我要留言

立即登入留言